import axios from 'axios';
import * as cheerio from 'cheerio';
import { parseChapter, getHeaders } from './parser.js';
import { URL } from 'url';

// 延迟函数
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

// 网站配置
const SITE_CONFIGS = {
    // 3yt.org 网站配置
    '3yt.org': {
        titleSelector: '.detail .name strong',
        authorSelector: '.detail .author a',
        chapterListSelector: '.read li',
        chapterTitleSelector: 'a',
        chapterUrlSelector: 'a',
        chaptersPerPage: 50,
        getPageUrl: (baseUrl, page) => {
            const cleanUrl = baseUrl.replace(/\/$/, '');
            return page === 1 ? cleanUrl : `${cleanUrl}_${page}/`;
        },
        getFullChapterUrl: (baseUrl, chapterUrl) => {
            const urlObj = new URL(baseUrl);
            return `${urlObj.protocol}//${urlObj.hostname}${chapterUrl}`;
        }
    },
    // 笔趣阁网站配置
    'xbiquge.la': {
        titleSelector: '#info h1',
        authorSelector: '#info p:contains("作者")',
        chapterListSelector: '#list dd',
        chapterTitleSelector: 'a',
        chapterUrlSelector: 'a',
        chaptersPerPage: 0, // 0表示所有章节都在一页
        getPageUrl: (baseUrl) => baseUrl, // 笔趣阁没有分页
        getFullChapterUrl: (baseUrl, chapterUrl) => {
            const urlObj = new URL(baseUrl);
            return `${urlObj.protocol}//${urlObj.hostname}${chapterUrl}`;
        }
    },
    // 顶点小说网站配置
    'dingdiann.com': {
        titleSelector: '.bookname h1',
        authorSelector: '.small span:contains("作者")',
        chapterListSelector: '#list dd',
        chapterTitleSelector: 'a',
        chapterUrlSelector: 'a',
        chaptersPerPage: 0,
        getPageUrl: (baseUrl) => baseUrl,
        getFullChapterUrl: (baseUrl, chapterUrl) => {
            const urlObj = new URL(baseUrl);
            return `${urlObj.protocol}//${urlObj.hostname}${chapterUrl}`;
        }
    },
    // 默认配置（通用）
    'default': {
        titleSelector: 'h1, .title, .book-title',
        authorSelector: '.author, .writer, .book-author',
        chapterListSelector: '.chapter-list li, .chapters li, .list-chapter li',
        chapterTitleSelector: 'a',
        chapterUrlSelector: 'a',
        chaptersPerPage: 0,
        getPageUrl: (baseUrl) => baseUrl,
        getFullChapterUrl: (baseUrl, chapterUrl) => {
            try {
                return new URL(chapterUrl, baseUrl).href;
            } catch (e) {
                return chapterUrl;
            }
        }
    }
};

// 获取网站配置
function getSiteConfig(url) {
    const urlObj = new URL(url);
    const hostname = urlObj.hostname.replace(/^www\./, '');

    // 检查是否有匹配的网站配置
    for (const site in SITE_CONFIGS) {
        if (hostname.includes(site)) {
            console.log(`检测到网站: ${site}`);
            return SITE_CONFIGS[site];
        }
    }

    // 如果没有匹配的配置，使用默认配置
    console.log('未找到匹配的网站配置，使用默认配置');
    return SITE_CONFIGS.default;
}

// 计算总页数
function calculateTotalPages(totalChapters, chaptersPerPage) {
    if (chaptersPerPage <= 0) return 1; // 如果每页章节数为0，表示所有章节都在一页
    return Math.ceil(totalChapters / chaptersPerPage);
}

// 爬取小说信息和章节列表
async function getNovelInfo(url, maxChapters = 1055) {
    try {
        // 获取网站配置
        const siteConfig = getSiteConfig(url);

        // 获取第一页内容
        const response = await axios.get(url, {
            headers: getHeaders(),
            timeout: 10000,
            maxRedirects: 5
        });
        const $ = cheerio.load(response.data);

        // 获取小说标题和作者
        let title = $(siteConfig.titleSelector).first().text().trim();
        let author = $(siteConfig.authorSelector).first().text().trim();

        // 处理作者信息（可能包含"作者："前缀）
        author = author.replace(/^作者[：:]\s*/, '');

        // 计算总页数（基于最大章节数和每页章节数）
        const chaptersPerPage = siteConfig.chaptersPerPage;
        const totalPages = calculateTotalPages(maxChapters, chaptersPerPage);
        console.log(`预计共有 ${totalPages} 页目录${chaptersPerPage > 0 ? `（每页${chaptersPerPage}章）` : ''}`);

        // 获取所有页面的章节列表
        const chapters = [];
        for (let page = 1; page <= totalPages; page++) {
            const pageUrl = siteConfig.getPageUrl(url, page);
            console.log(`正在获取第 ${page}/${totalPages} 页目录: ${pageUrl}`);

            try {
                let $page = $;
                // 如果不是第一页，需要重新请求
                if (page > 1) {
                    // 使用前一页作为referer
                    const referer = page > 2 ? siteConfig.getPageUrl(url, page - 1) : url;
                    const pageResponse = await axios.get(pageUrl, {
                        headers: getHeaders(referer),
                        timeout: 10000,
                        maxRedirects: 5
                    });
                    $page = cheerio.load(pageResponse.data);
                }

                $page(siteConfig.chapterListSelector).each((index, element) => {
                    const $element = $page(element);
                    const chapterUrl = $element.find(siteConfig.chapterUrlSelector).attr('href');
                    const chapterTitle = $element.find(siteConfig.chapterTitleSelector).text().trim();

                    if (chapterUrl && chapterTitle) {
                        chapters.push({
                            url: siteConfig.getFullChapterUrl(url, chapterUrl),
                            title: chapterTitle
                        });
                    }
                });

                console.log(`第 ${page} 页找到 ${$page(siteConfig.chapterListSelector).length} 章`);
            } catch (error) {
                console.error(`获取第 ${page} 页失败:`, error.message);
                // 如果是404错误，可能是已经到达最后一页
                if (error.response && error.response.status === 404) {
                    console.log(`第 ${page} 页不存在，可能已到达最后一页`);
                    break;
                }
                // 其他错误则继续尝试下一页
            }

            // 添加延迟，避免请求过快
            if (page < totalPages) {
                await sleep(1000);
            }
        }

        return {
            title,
            author,
            chapters
        };
    } catch (error) {
        console.error('获取小说信息失败:', error.message);
        throw error;
    }
}

// 爬取小说内容
export async function crawlNovel(url, startChapter = 1, chapterLimit = 1055, delay = 1000) {
    try {
        // 获取网站配置
        const siteConfig = getSiteConfig(url);
        console.log(`检测到网站类型: ${Object.keys(SITE_CONFIGS).find(site => url.includes(site)) || 'default'}`);

        console.log('正在获取小说信息...');
        const novelInfo = await getNovelInfo(url, chapterLimit);
        console.log(`小说标题: ${novelInfo.title}`);
        console.log(`作者: ${novelInfo.author}`);
        console.log(`共找到 ${novelInfo.chapters.length} 个章节`);

        // 确定要爬取的章节范围
        const endChapter = Math.min(
            startChapter + chapterLimit - 1,
            novelInfo.chapters.length
        );

        console.log(`将爬取第 ${startChapter} 章到第 ${endChapter} 章，共 ${endChapter - startChapter + 1} 章`);

        // 存储爬取的内容
        const novel = {
            title: novelInfo.title,
            author: novelInfo.author,
            source: url,
            chapters: []
        };

        // 爬取每一章节
        for (let i = startChapter - 1; i < endChapter; i++) {
            const chapter = novelInfo.chapters[i];
            console.log(`正在爬取: ${chapter.title} (${i + 1}/${endChapter})`);

            try {
                // 使用网站特定的延迟
                const siteDelay = delay;
                const content = await parseChapter(chapter.url, siteDelay);
                novel.chapters.push({
                    title: chapter.title,
                    content: content,
                    url: chapter.url
                });

                // 延迟一段时间再爬取下一章
                if (i < endChapter - 1) {
                    const nextDelay = Math.floor(delay * (1 + Math.random() * 0.5)); // 添加随机延迟
                    console.log(`等待 ${nextDelay}ms 后继续...`);
                    await sleep(nextDelay);
                }
            } catch (error) {
                console.error(`爬取章节失败: ${chapter.title}`, error.message);
                // 继续爬取下一章
                continue;
            }
        }

        return novel;
    } catch (error) {
        console.error('爬取小说失败:', error.message);
        throw error;
    }
}